<?php
class objectDef {
	public $className;
	public $idIsGuid;
	public $definition;
	public $charset;
	public $description;
	public $orderFields;
	public $attributes;
    public $label;
    public $labelPlural;
    public $isReadOnly;
    public $canBeDeleted;
    public $hasStatus;
    public $descriptor;
    public $timeStampable;
    public $formExtraTemplate;
    public $showExtraTemplate;
    public $indexExtraTemplate;
    public $classExists;
    public $hasAttach;
    public $filesPathName;
    public $attributesWithTotal;
    
        
   	function __construct($className){
   		$this->className = $className;
		$util = new Util();
		$definition = $util->getOEDef($className);
		if($definition){
			$this->classExists = true; 
		}else{
			$this->classExists = false;
		}
		$this->charset = $util->getCharset();   		
   		$this->attributes = $definition['attributes'];
   		$i18N = sfContext::getInstance()->getI18N();
		$this->label =  $i18N->__($definition['general']['labelSingular'],null,'forms');
		$this->labelPlural =  $i18N->__($definition['general']['labelPlural'],null,'forms');
   		$this->timeStampable = $definition['general']['timeStampable'];
   		$this->indexExtraTemplate = $definition['general']['indexExtraTemplate'];
   		$this->description = $i18N->__($definition['general']['description'],null,'forms');
   		$this->orderFields = $definition['general']['orderFields'];
   		$this->isReadOnly = $definition['general']['isReadOnly'];
   		$this->canBeDeleted = $definition['general']['canBeDeleted'];
   		$this->hasStatus = $definition['general']['hasStatus'];
   		$this->hasAttach = $definition['general']['hasAttach'];
   		$this->descriptor = $definition['general']['descriptor'];
   		$this->formExtraTemplate = $definition['general']['formExtraTemplate'];
   		$this->showExtraTemplate = $definition['general']['showExtraTemplate'];
   		$this->indexExtraTemplate = $definition['general']['indexExtraTemplate'];
   		$this->filesPathName = $definition['general']['filesPathName'];
   		$this->attributesWithTotal = $definition['attributesWithTotal'];
   		unset($definition);
   		unset($util);
   	}

   	public function idIsGuid(){
   	 	$idIsGuid = false;
 		if(isset($this->attributes['id'])){
 			$idAttDef = $this->attributes['id'];
 			if($idAttDef['type']=='string'){
 				$idIsGuid = true;
 			}
 		}
 		return $idIsGuid;
   	}
   	
   	/*
   	 * Returns an array with all attributes definitions of the same type
   	 * 
   	 * @param string $datatype
   	 * 
   	 * return array
   	 * 
   	 * */
   	
   	public function getAttributesByType( $datatype)
   	{
   		$returnArray = array();
   		foreach($this->attributes as $fieldName => $att)
   		{
   			if($att['type'] == $datatype)
   			{
   				$returnArray[$fieldName] = $att;
   			}
   		}
   		return $returnArray;
   	}
   	
	public function renderDefault($item, $hide,$style = 'table', $fieldSets = false)
   	{
   		$i18N = sfContext::getInstance()->getI18N();
   		
   		if(is_null($hide))
   			$hide = array();
		
   		$html = '';
		if($fieldSets == false){
	   		if($style=='div')
			{
				$html .=  '<div>';
	     	}
			elseif($style=='span')
	     	{
	     		$html .= '<span>';
	     	}
	     	else
			{
				$html .= '<table>';
	     	}
		}
		$section = '';
	    
     	foreach($this->attributes as $fieldName => $att)
		{
			if($fieldSets and $att['show'] and !in_array($fieldName, $hide))
			{ 
				if($section != $att['section'])
				{
					if($section !='')
					{
						if($style=='table')
						{
							$html .= '</table>';
				     	}							
						$html .= '</fieldset>';
					}
					$html .= '<fieldset id="' . Util::stripAccents2($att['section'], true) . '"><legend>'. $att['section'] .'</legend>';
					if($style=='table')
					{
						$html .= '<table>';
			     	}
				}
			}
			if($att['show'] and !in_array($fieldName, $hide) and $att['type'] != 'List' and $att['type'] != 'BOList')
			{
				if($style=='div')
				{
					$html .=  '<div>';
		     	}
				elseif($style=='span')
		     	{
					$html .= '<span>';
		     	}
		     	else
				{
					$html .= '<tr>';
		     	}
				$html .= $this->renderAttribute($item, $fieldName, $style);
				if($style=='div')
				{
					$html .=  '</div>';
		     	}
				elseif($style=='span')
		     	{
		     		$html .= '</span><br />';
				}
				else
				{
					$html .= '</tr>';
				}
				
			}
			elseif($att['show'] and !in_array($fieldName, $hide) and $att['type'] == 'BOList')
			{
				//It doesnt' work for the List, because the link_to helper cant resolve the application name
				if($att['type'] == 'List')
				{
					$addNew = !$att['readOnly'];
					$addActions = !$att['readOnly'];	
					$fieldName2 = $fieldName;
				}
				else
				{
					$addNew = false;
					$addActions = false;
					$fieldName2 = $fieldName.'_id';
				}
				//Si no funciona, revisar la definicion de la tabla de items. 
				//El foreign field tiene que apuntar al campo de la tabla principal.
				$resultArray = $this->getRelatedObjectdef($fieldName2 , 1);
    			$relatedObjectDef = $resultArray[1];
    			$relationName = $resultArray[0];
    			if($relationName!='')
    			{
    				$html .= '<div id="' . $fieldName .'" class="itemswrapper">';
    				if($style=='table') $html .= '<tr><td colspan="2">';
    				$html .= '<fieldset><legend>'. $i18N->__($att['label']).'</legend>';
    				$html .= $relatedObjectDef->renderListTable($item->$relationName, '', array(), false, $addNew, $addActions, false );
    				$html .= '</fieldset>';
    				if($style=='table') $html .= '</td></tr>';
    				$html .= '</div>';	
    			}
			}
			if($fieldSets and $att['show'] and !in_array($fieldName, $hide)) 
				$section = $att['section'];
		}
		
		if($fieldSets == false){
			if($style=='div')
			{
				$html .= '</div>';
			}
			elseif($style=='span')
			{
				$html .= '</span><br />';
		    }
		    else
		    {
				$html .= '</table>';
		    }	
		}
	    if($fieldSets){
	    	if($style=='table')
			{
				$html .= '</table>';
	     	}	
	    	$html .= '</fieldset>';	
	    }	
		return $html;
   	}
   	
   	public function renderDefaultForm($form, $formAction, $module, $className, $hide = null , $buttons = true, $target='',$addFieldSet=false, $ajaxForm=false, $formDivId = '', $attributes = array()){
   		$i18N = sfContext::getInstance()->getI18N();
   		$html = '';
   		if(!isset($formDivId)){
   			$formDivId = get_class($form);
   		}
   		if(!isset($formAction)){
			$formAction = url_for($module.'/'.($form->getObject()->isNew() ? 'create?className='.$className : 'update').(!$form->getObject()->isNew() ? '?id='.$form->getObject()->getId().'&className='.$className : ''));
   		}
   		if($target!=''){
			$target = "target=$target";
		}
		if($addFieldSet)
			$html.='<fieldset><legend>'. $addFieldSet.'</legend>';
		if($ajaxForm)
			$html.='<a id="addNotif" style="float:right;" onclick="hideForm(\''.$formDivId.'\');" href="#"><img src="/images/icons/16/close.png" title="'. $i18N->__('Close').'"></img></a>';
		$html.='<div id="errorDisplayHautForm'.$className.'" class="errorDisplay">&nbsp;</div>';
		if($form->isMultipart()) {
			$enctype = 'enctype="multipart/form-data"';		
		}else{
			$enctype = '';
		}
		
		if(in_array('class', array_keys($attributes))){
			$strAtributes = '';	
		}else{
			$strAtributes = 'class="defaultForm"';
		}	 
		foreach($attributes as $name => $value){
			$strAtributes .= "$name=\"$value\"";	
		}
		$html .= '<form id="Form'.$className.'" action="'. $formAction .'" method="post" '. $enctype .'tmt:validate = "true" tmt:callback="errorOnLabels" ' . $target. ' ' . $strAtributes . '>';
		if(!$form->getObject()->isNew())
			$html.='<input type="hidden" name="sf_method" value="put" />';
		$html .= $form->renderGlobalErrors();
		if ($form->isCSRFProtected())
		 	$html.= $form['_csrf_token'];
		if($this->description){
			$html.= '<fieldset><legend>'. $i18N->__("General Information").'</legend>';
		  	$html.= '<div class="description">'.$this->description.'</div>';
		  	$html.= '</fieldset>';
		}	
		$section = '';
		foreach($this->attributes as $fieldName => $att){
			if($section != $att['section']){
	        	if($section !='')
	        		$html.= '</fieldset>';
	        	
	            $html.= '<fieldset id="'. Util::stripAccents2($att['section'], true).'"><legend>'.$i18N->__($att['section'],null,'forms').'</legend>';
			}
		    $html .= $this->renderAttributeWidget($form, $fieldName, $hide);; 
	  		$section = $att['section'];		  	
		}
		if($buttons){
		  	$html.= '<div class="buttons">';
		  	$sf_user = sfContext::getInstance()->getUser();
		  	$owner = $sf_user->getAttribute('ownerId');
		  	if($ajaxForm){
		  		$html.= '<a href="javascript:hideForm(\''.$formDivId.'\');">';
				$html.= '<img src="/images/icons/64/cancel.png" title="'. $i18N->__('Cancel').'"></img>';
				$html.= '</a>';
		  	}else{  
		       	if($owner <> '' and $owner!=$form->getObject()->getId() ){
			  		$ownerClass = $sf_user->getAttribute('ownerClass');
			  		$ownerModule = $sf_user->getAttribute('ownerModule');
				    if(isset($ownerModule)){
				    	if($ownerModule=='')
				    		$ownerModule = $module ;
				    }
			  		$html.= link_to('<img title="'.$i18N->__('Go back').'" src="/images/icons/64/cancel.png"/>', $ownerModule.'/show?id='.$owner.'&className='.$ownerClass);
		       	}else{
		      		$html.= link_to('<img title="'.$i18N->__('Go back').'" src="/images/icons/64/cancel.png"/>', $module.'/index?className='.$className);
	          	}
		  	}			
          	if (!$form->getObject()->isNew()){
          		if($this->canBeDeleted){
            		$html.= '&nbsp;'.link_to('<img title="'.$i18N->__('Delete').'" src="/images/icons/64/delete.png"/>', $module.'/delete?id='.$form->getObject()->getId().'&className='.$className,  array('method' => 'delete', 'confirm' => $i18N->__('Are you sure')));
          		}
          	}
          	$html.= '<a href="javascript:submitForm(\'Form'.$className.'\');">';
			$html.= '<img src="/images/icons/64/confirm.png" title="'. $i18N->__('Save').'"></img>';
			$html.= '</a>';
          	
          	//$html.= '<input id="submit'.get_class($form).'" name="submit" title="'. $i18N->__('Save').'" type="image" src="/images/icons/64/confirm.png" onclick="tmt.validator.validateForm(\'Form'.$className.'\');">';
          //	$html.= '<a href="javascript:;" onclick="tmt.validator.validateForm(\'Form'.$className.'\')">Validate form</a>';
			$html.= '</div>';
		}		
/*
			<h1>
				  <div class="buttons">	
				<?php // echo __('To add a person you want to add to the notification chain complete the form and click sur this icon')?>
				
				<input name="Submit" title="<?php echo __('Save')?>" type="image" src="/images/icons/32/confirm.png">
				<iframe id="addParticipantTarget" name="addParticipantTarget" style="width:0;height:0;border:0px solid #fff;" src="#" ></iframe>
				</div> 	 
			</h1>
*/			
		$html.= '</form>';   	
		if($addFieldSet)
			$html.= '</fieldset>';
		return $html;
   	}
   	
   	public function renderDefaultForm2($form, $formAction, $module, $className, $hide = null , $buttons = true, $target='',$addFieldSet=false, $ajaxForm=false, $formDivId = '', $attributes = array()){
   		$i18N = sfContext::getInstance()->getI18N();
   		$html = '';
   		if(!isset($formDivId)){
   			$formDivId = get_class($form);
   		}
   		if(!isset($formAction)){
			$formAction = url_for($module.'/'.($form->getObject()->isNew() ? 'create?className='.$className : 'update').(!$form->getObject()->isNew() ? '?id='.$form->getObject()->getId().'&className='.$className : ''));
   		}
   		if($target!=''){
			$target = "target=$target";
		}
		if($addFieldSet)
			$html.='<fieldset><legend>'. $addFieldSet.'</legend>';
		$html.='<div id="errorDisplayHautForm'.$className.'" class="errorDisplay">&nbsp;</div>';
		if($form->isMultipart()) {
			$enctype = 'enctype="multipart/form-data"';		
		}else{
			$enctype = '';
		}
		
		if(in_array('class', array_keys($attributes))){
			$strAtributes = '';	
		}else{
			$strAtributes = 'class="defaultForm"';
		}	 
		foreach($attributes as $name => $value){
			$strAtributes .= "$name=\"$value\"";	
		}
		$html .= '<form id="Form'.$className.'" action="'. $formAction .'" method="post" '. $enctype .'tmt:validate = "true" tmt:callback="errorOnLabels" ' . $target. ' ' . $strAtributes . '>';
		if(!$form->getObject()->isNew())
			$html.='<input type="hidden" name="sf_method" value="put" />';
		$html .= $form->renderGlobalErrors();
		if ($form->isCSRFProtected())
		 	$html.= $form['_csrf_token'];
		if($this->description){
			$html.= '<fieldset><legend>'. $i18N->__("General Information").'</legend>';
		  	$html.= '<div class="description">'.$this->description.'</div>';
		  	$html.= '</fieldset>';
		}	
		$section = '';
		foreach($this->attributes as $fieldName => $att){
			if($section != $att['section']){
	        	if($section !='')
	        		$html.= '</fieldset>';
	        	
	            $html.= '<fieldset id="'. Util::stripAccents2($att['section'], true).'"><legend>'.$i18N->__($att['section'],null,'forms').'</legend>';
			}
		    $html .= $this->renderAttributeWidget($form, $fieldName, $hide);; 
	  		$section = $att['section'];		  	
		}
		if($buttons){
		  	$html.= '<div class="buttons">';
		  	$sf_user = sfContext::getInstance()->getUser();
		  	$owner = $sf_user->getAttribute('ownerId');
		  	if(!isset($owner)) $owner = $form->getObject()->owner_id;
		  	if($ajaxForm){
		  		if (!$form->getObject()->isNew()){
	          		if($this->canBeDeleted){
	            		//$html.= '&nbsp;'.link_to('<img title="'.$i18N->__('Delete').'" src="/images/icons/64/delete.png"/>', $module.'/delete?id='.$form->getObject()->getId().'&className='.$className,  array('method' => 'delete', 'confirm' => $i18N->__('Are you sure')));
	          			$html.= '&nbsp;<a id="deleteItem" style="float:right;" onclick="deleteItem(\''. get_class($form->getObject()) . '\', \'\', '.$form->getObject()->id.', '.$owner.');" href="#"><img src="/images/icons/64/delete.png" title="'. $i18N->__('Delete').'"></img></a>';
		      		}
	    
	          		
	          	}
		  	}else{  
		       	if($owner <> '' and $owner!=$form->getObject()->getId() ){
			  		$ownerClass = $sf_user->getAttribute('ownerClass');
			  		$ownerModule = $sf_user->getAttribute('ownerModule');
				    if(isset($ownerModule)){
				    	if($ownerModule=='')
				    		$ownerModule = $module ;
				    }
			  		$html.= link_to('<img title="'.$i18N->__('Go back').'" src="/images/icons/64/cancel.png"/>', $ownerModule.'/show?id='.$owner.'&className='.$ownerClass);
		       	}else{
		      		$html.= link_to('<img title="'.$i18N->__('Go back').'" src="/images/icons/64/cancel.png"/>', $module.'/index?className='.$className);
	          	}

	          	if (!$form->getObject()->isNew()){
	          		if($this->canBeDeleted){
	            		$html.= '&nbsp;'.link_to('<img title="'.$i18N->__('Delete').'" src="/images/icons/64/delete.png"/>', $module.'/delete?id='.$form->getObject()->getId().'&className='.$className,  array('method' => 'delete', 'confirm' => $i18N->__('Are you sure')));
	          		}
	          	}
		  	}			
          	$html.= '<a href="javascript:submitForm(\'Form'.$className.'\');">';
			$html.= '<img src="/images/icons/64/confirm.png" title="'. $i18N->__('Save').'"></img>';
			$html.= '</a>';
          	
          	//$html.= '<input id="submit'.get_class($form).'" name="submit" title="'. $i18N->__('Save').'" type="image" src="/images/icons/64/confirm.png" onclick="tmt.validator.validateForm(\'Form'.$className.'\');">';
          //	$html.= '<a href="javascript:;" onclick="tmt.validator.validateForm(\'Form'.$className.'\')">Validate form</a>';
			$html.= '</div>';
		}		
		$html.= '</form>';   	
		if($addFieldSet)
			$html.= '</fieldset>';
		return $html;
   	}
   	
   	
   	public function renderAttributeWidget($form, $fieldName, $hide = null, $attributes = array()){
   		if(is_null($hide))
   			$hide = array();
   		$html = '';
   		$display = '';
   		if($this->isReadOnly) $attributes['disabled']='true';
   		$att = $this->attributes[$fieldName];
   		$divClassName = '';
   		if($att['type']!='List' and $att['type']!='BOList' and $att['type']!='function'){
			$fieldName2 = $fieldName;
			if($att['type']=='BO' or $att['type']=='BOList')
	   			{
	   				$fieldName2 = $fieldName.'_id';
	   			}
	   		if($att['type']=='CheckboxList')
	   			{
	   				$fieldName2 = $fieldName.'_list';
	   			}
	   		if(!isset($form[$fieldName2]))
			{
				return ''; //Field has been unsetted on the form configuration
			}
				
	   		if($att['type']=='tinyMCE'){
	   			$divClassName = 'class="tinyMCEWrapper"';
	   		}
	   		if(get_class($form)=='sfFormFieldSchema')
	   		{
	   			$hiddenFields = array();
	   		}	
	   		else 
	   		{
	   			$hiddenFields = $form->hiddenFields; 
	   		}
	   		if($form->getWidget($fieldName2)->isHidden() or in_array($fieldName, $hiddenFields) or  in_array($fieldName, $hide)){
	   			$display = "display: none;";	
	   		}
	   		$html .= '<div id="wrapper'.$fieldName.'" '. $divClassName .' style="'.$display.'">';
			if($att['show'] and !in_array($fieldName, $hide) ){
			  		if($att['description']){
	  					$html .= '<div class="description">';
	  					$html .= $att['description'];
	  					$html .= '</div>';
			  		}
				  	
				  	if($att['type']=='file'){
				  		if(get_class($form)!='sfFormFieldSchema')
				  		{
					  		$namefile = $form->getObject()->$fieldName; 
							if($namefile!=''){
								$attributes['value'] = $namefile;
							}
				  		}
						$html .= $form[$fieldName2]->renderRow($attributes);
						if(get_class($form)!='sfFormFieldSchema')
				  		{
				  	    	$html .= $this->renderFile($form->getObject(), $fieldName, $att, '', true);
				  		}
					}else{
						$html .= $form[$fieldName2]->renderRow($attributes);
					}
				}else{
					$html .= $form[$fieldName2]->render($attributes);
			  	}
			  	$html .= '<div id="notif'.$fieldName.'"></div></div>';
		}	 	
		
		return $html;	
   	}
   	
   	public function renderAttribute($object, $fieldName, $style='span', $labelAttributes = array(), $valueAttributes = array()){
   		$html = '';
   		$labelAtt = '';
   		$valueAtt = '';
   		foreach ($labelAttributes as $attribute => $value){
   			$labelAtt .= "$attribute = $value";
   		}
   		foreach ($valueAttributes as $attribute => $value){
   			$valueAtt .= "$attribute = $value";
   		}
   		if($style=='div' or $style=='span')
		{
			$html .= '<div id="'.$fieldName.'" class = "label_value_wrapper">';
			$html .= '<span class = "label label_' . $this->attributes[$fieldName]['type'] .'" ' . $labelAtt . '><b>'.$this->renderLabel($fieldName).' </b> </span>';
			$html .= '<span class = "value value_' . $this->attributes[$fieldName]['type'] .'" ' . $valueAtt . '>'.$this->renderAttributeValue($object, $fieldName).'</span>';
			$html .= '</div>';
		}
		else
		{
			$html .= '<th width="50%" ' . $labelAtt . '>'.$this->renderLabel($fieldName).' : </th>';
			$html .= '<td ' . $valueAtt . '>'.$this->renderAttributeValue($object, $fieldName).'</td>';
		}
		return $html;
   	}
   	
   	public function renderAttributeValue($object, $fieldName){
   		sfProjectConfiguration::getActive()->loadHelpers('format');
   		$util = new Util();
   		$self = $object;
   		if(is_object($self)){
   			$useObject = true;
   		}else{
   			$useObject = false;
   		}
   		$att = $this->attributes[$fieldName];
   		$i18N = sfContext::getInstance()->getI18N();
   		$html = '';
   		if($att['type']=='boolean'){
   			if($useObject){
    	   		$html .= $self->$fieldName ? $i18N->__('yes'): $i18N->__('no');
   			}else{
    	   		$html .= $self[$fieldName] ? $i18N->__('yes'): $i18N->__('no');
    	   	}    	    	
        }elseif($att['type']=='image'){
           	if($useObject){
    	   		$img = $self->$fieldName;
   			}else{
    	   		$img = $self[$fieldName];
    	   	} 
    	   	$html .= $this->renderImage($self, $fieldName, $att);
    		//'<img src=" '/'.str_replace("\"","/",sfConfig::get('sf_icons_dir_name')).'/'.$self->$fieldName " alt="$self->$fieldName"
        }elseif($att['type']=='file'){
        	$html .= $this->renderFile($self, $fieldName, $att);
        	//include_partial('renderFile', array('self' => $self,'fieldName' => $fieldName, 'label' => '', 'origin' => 'upload'));
       	}elseif($att['type']=='enum'){
       		$options = $util->getArrayFromStr($util->stripAccents2($att['enumValues']),';',false,'=>');
       		$valeur = $self[$fieldName];
       		if(in_array($valeur,array_keys($options)))
			{
				$html .=  $options[$valeur];
			}else{
				$html .= $valeur;	
			}
    	}elseif($att['type']=='array'){
    		$html .= '<div>';
			if($useObject){
				if($self->$fieldName){
					foreach ($self->$fieldName as $key => $value)
						{
							if($att['relatedClass']!=''){
								$relatedClass = $att['relatedClass'];
								$relatedObjDef = new objectDef ($relatedClass);
			        			if($relatedObjDef->classExists){
									$descriptor = $relatedObjDef->descriptor;
		        					$obj =  Doctrine::getTable($relatedClass)->find($value);
		        					if($obj){
		        						$html .=  $obj->$descriptor .'<br>';
		        					}else{
		        						$html .=  $value .'<br>';
		        					}
								}else{
									$html .= $self->$fieldName->__toString()  .'<br>';
								}
							}else{
								$html .= $value  .'<br>';
							}
					}
				}
			}else{
				if($self[$fieldName]){
					foreach ($self[$fieldName] as $key => $value)
						{
							if($att['relatedClass']!=''){
								$relatedClass = $att['relatedClass'];
								$relatedObjDef = new objectDef ($relatedClass);
			        			if($relatedObjDef->classExists){
									$descriptor = $relatedObjDef->descriptor;
		        					//$obj =  Doctrine::getTable($relatedClass)->find($value);
		        					$q = Doctrine_Query::create()
    									->select('id')
    									->addSelect($descriptor)
									    ->from($relatedClass)
									    ->where('id = ?');
									$result = $q->execute(array($value), Doctrine_Core::HYDRATE_NONE);
									if(count($result)>0){
		        						$html .=  $result[0][1] .'<br />';
									}else{
										$html .= '<br />';
									}
								}else{
									$html .= $key  .'<br />';
								}
							}else{
								$html .= $value  .'<br/>';
							}
					}
				}				
			}
			$html .= '</div>';
    	}elseif($att['type']=='List'){
    	    		
    	}elseif($att['type']=='BOList'){
    		$resultArray = $this->getRelatedObjectdef($fieldName.'_id' , 1);
    		$relatedObjectDef = $resultArray[1];
    		$relationName = $resultArray[0];
    		if($relationName!=''){
    				$html .= '<fieldset><legend>'. $i18N->__($att['label']).'</legend>';
    				$html .= $relatedObjectDef->renderListTable($self[$relationName], '', array(), false, false, false, false );
    				$html .= '</fieldset>';
    		}    		
    	}elseif($att['type']=='date'){
		  $culture = sfContext::getInstance()->getUser()->getCulture(); 
		  $dateFormatter = new sfDateFormat($culture);
		  if($self[$fieldName]!=''){
		  	  $html .= $dateFormatter->format($self[$fieldName], 'dd/MM/yyyy', null);
		  }
    	}elseif($att['type']=='decimal'){
		  $culture = sfContext::getInstance()->getUser()->getCulture(); 
		  $formatter = new sfNumberFormat($culture);
		  if($self[$fieldName]!=''){
		  	  $html .= $formatter->format($self[$fieldName], '#.00');
		  }
    	    //$html .= format_date($self->$fieldName,'d/M/y' );  		
    	}elseif($att['type']=='timestamp'){
		  $culture = sfContext::getInstance()->getUser()->getCulture(); 
		  $dateFormatter = new sfDateFormat($culture);
		  if($self[$fieldName]!=''){
		  	  $html .= $dateFormatter->format($self[$fieldName], 'dd/MM/yyyy HH:ss', null);
		  }
    	    //$html .= format_date($self->$fieldName,'d/M/y' );  		
    	}elseif($att['type']=='blob'){
    	 	$html .= ' ' . nl2br($self[$fieldName]);
    	}elseif($att['type']=='function'){
    		if($useObject){
    			$html .= $self->$fieldName();
    		}else{
    			/*I have to get the object to execute de function*/
    			$obj =  Doctrine::getTable($this->className)->find($self['id']);
    			$html .= $obj->$fieldName();
    		}
    	}elseif($att['type']=='CheckboxList'){
        		$relatedClass= $att['relatedClass'];
				$refClass = $att['refClass'];
        		$relatedObjDef = new objectDef ($relatedClass);
        		$refObjDef = new objectDef ($refClass);
        		if($relatedObjDef->classExists){
        			$descriptor = $relatedObjDef->descriptor;
					$relation = $this->getRelationDef($fieldName);
					$foreingField = $relation->getForeign();
					$alias = $relation->getAlias();
					
					$q =  Doctrine::getTable($this->className)
		 				->createQuery('a')
		 				->select('a.id');
        			$q->innerJoin('a.' . $refClass . ' b');
        			$q->where('id = ?',$self['id']);
        			
        			$relation = $this->getRelationDef($refClass);
        			$relations = Doctrine::getTable($refClass)->getRelations();
        			foreach($relations as $item){
        				if(strtolower($relatedClass)==strtolower($item->getClass())){
        					$relation = $item;
        				}
        			}
        			$identifiers = Doctrine::getTable($refClass)->getIdentifier();
        			if(is_array($identifiers)){
        				foreach($identifiers as $ident){
        					$q->addSelect('b.' . $ident);
        				}
        			}else{
        				$q->addSelect('b.' . Doctrine::getTable($refClass)->getIdentifier()); //The left side of the join between the aliases 'b' and 'c' must have at least the primary key field(s) selected.	
        			}        			$q->innerJoin('b.' . $relation->getAlias() . ' c');
        			$q->addSelect('c.' . $relatedObjDef->descriptor);
					$results = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
					foreach($results as $result){
						foreach($result[$refClass] as $item){
							$html .=  $item[$relatedClass][$descriptor] .'<br />';
						}
					}
				}else{
					foreach($self->$fieldName as $item){
						$html .= $item.'<br />';;
					}
					$html .= $key  .'<br>';
				}
        }else{
        	if($useObject){
	        	if($att['type']=='BO' or $att['type']=='BOList'){
					$fieldName2 = $fieldName.'_id';
	        	}else{
	        		$fieldName2 = $fieldName;
	        	}
	        	if($self[$fieldName2]!=''){
	        		if(isset($relatedObjDef))
	        			unset($relatedObjDef);
	        		$resultArray = $this->getRelatedObjectdef($fieldName2);
    				$relatedObjDef = $resultArray[1];
    				$relationName = $resultArray[0];
	        		if(isset($relatedObjDef)){
	        			if($relatedObjDef->classExists){
		        			$descriptor = $relatedObjDef->descriptor;
		        			$html .=  $self->$relationName->$descriptor;
	        			}else{
	        				$html .= $self->$relationName->__toString();
	        			}
	        		}else{
	        			if(substr($self->$fieldName2, 0, 4) == 'http' or substr($self->$fieldName2, 0, 3) == 'www'){
	        				if(substr($self->$fieldName2, 0, 3) == 'www'){
	        					$link = 'http://' . $self->$fieldName2;
	        				}else{
	        					$link = $self->$fieldName2;
	        				}
	        				$html .= link_to( $self->$fieldName2, $link, array('target'=>'_blank'));
	        			}else{
	        				$valeur = $self->$fieldName2;
		        			$action = $this->getCandidatesArray(false);
							if(in_array($valeur,array_keys($action)))
							{
								$valeur = $action[$valeur];
							}
							if($att['pattern']=='tel'){
								if(function_exists('format_phone'))
								{
									$valeur = format_phone($valeur, '00 00 00 00 00');
								}
							}elseif($att['pattern']=='email'){
								$valeur = '<a href="mailto:' . $valeur . '" >' . $valeur . '</a>';
							}							
	        				$html .= $valeur;
	        			}
	        		}
	        	}
        	}else{
        		if($att['type']=='BO' or $att['type']=='BOList'){
        			$fieldName2 = $fieldName.'_id';
	        		if($att['relatedClass']!=''){
	        			$alias = $att['alias'];
	        			$relatedClass = $att['relatedClass'];
						$relatedObjDef = new objectDef ($relatedClass);
			        	if($relatedObjDef->classExists){
							$descriptor = $relatedObjDef->descriptor;
							$html .=  $self[$alias][$descriptor];
						}else{
							$html .= $self[$fieldName2] ;
						}
						unset($relatedObjDef);
					}else{
						$html .= $self[$fieldName2] ;
					}
        		}else{
        			if(substr($self[$fieldName], 0, 4) == 'http' or substr($self[$fieldName], 0, 3) == 'www'){
	        			$html .= link_to( $self[$fieldName], $self[$fieldName], array('target'=>'_blank'));
	        		}else{
	        			$valeur = $self[$fieldName];
		        		$action = $this->getCandidatesArray(false);
						if(in_array($valeur,array_keys($action)))
						{
							$valeur = $action[$valeur];
						}
						if($att['pattern']=='tel'){
							if(function_exists('format_phone'))
							{
								$valeur = format_phone($valeur, '00 00 00 00 00');
								
							}
						}elseif($att['pattern']=='email'){
							$valeur = '<a href="mailto:' . $valeur . '">' . $valeur . '</a>';
						}
	        			$html .= $valeur;
	        		}	        			
        		}
        	}
        }
        return $html;
   	}
   	
   	/* Function to show values from an array represantation of an object
   	 * It can be used when you want to render the array returned by sfForm::getValues() function
   	 * 
   	 *  @param array $array  
   	 *  @param string $fieldName
   	 *  
   	 *  return string
   	 * */
   	
   	public function renderAttributeValueFromArray($array, $fieldName){
   		sfProjectConfiguration::getActive()->loadHelpers('format');
   		$util = new Util();
   		$self = $array;
   		$att = $this->attributes[$fieldName];
   		$i18N = sfContext::getInstance()->getI18N();
   		$html = '';
   		if($att['type']=='boolean'){
    	   	$html .= $self[$fieldName] ? $i18N->__('yes'): $i18N->__('no');
        }elseif($att['type']=='image'){
   	   		$img = $self[$fieldName];
    	   	$html .= $this->renderImage($self, $fieldName, $att);
    		//'<img src=" '/'.str_replace("\"","/",sfConfig::get('sf_icons_dir_name')).'/'.$self->$fieldName " alt="$self->$fieldName"
        }elseif($att['type']=='file'){
        	$html .= $this->renderFile($self, $fieldName, $att);
        	//include_partial('renderFile', array('self' => $self,'fieldName' => $fieldName, 'label' => '', 'origin' => 'upload'));
       	}elseif($att['type']=='enum'){
       		$options = $util->getArrayFromStr($util->stripAccents2($att['enumValues']),';',false,'=>');
       		$valeur = $self[$fieldName];
       		if(in_array($valeur,array_keys($options)))
			{
				$html .=  $options[$valeur];
			}else{
				$html .= $valeur;	
			}
    	}elseif($att['type']=='array'){
    		$html .= '<div>';
			if(isset($self[$fieldName])){
				foreach ($self[$fieldName] as $key => $value)
				{
					if($att['relatedClass']!=''){
						$relatedClass = $att['relatedClass'];
						$relatedObjDef = new objectDef ($relatedClass);
			    		if($relatedObjDef->classExists){
							$descriptor = $relatedObjDef->descriptor;
		        			//$obj =  Doctrine::getTable($relatedClass)->find($value);
		        			$q = Doctrine_Query::create()
    							->select('id')
    							->addSelect($descriptor)
							    ->from($relatedClass)
							    ->where('id = ?');
							$result = $q->execute(array($value), Doctrine_Core::HYDRATE_NONE);
							if(count($result)>0){
		        				$html .=  $result[0][1] .'<br />';
							}else{
								$html .= '<br />';
							}
						}else{
							$html .= $key  .'<br />';
						}
					}else{
						$html .= $value  .'<br/>';
					}
				}
			}				
			$html .= '</div>';
    	}elseif($att['type']=='List'){
    	    		
    	}elseif($att['type']=='BOList'){
    		$resultArray = $this->getRelatedObjectdef($fieldName.'_id' , 1);
    		$relatedObjectDef = $resultArray[1];
    		$relationName = $resultArray[0];
    		if($relationName!=''){
    				$html .= '<fieldset><legend>'. $i18N->__($att['label']).'</legend>';
    				$html .= $relatedObjectDef->renderListTable($self[$relationName], '', array(), false, false, false, false );
    				$html .= '</fieldset>';
    		}    		
    	}elseif($att['type']=='date'){
		  $culture = sfContext::getInstance()->getUser()->getCulture(); 
		  $dateFormatter = new sfDateFormat($culture);
		  if($self[$fieldName]!=''){
		  	  $html .= $dateFormatter->format($self[$fieldName], 'dd/MM/yyyy', null);
		  }
    	}elseif($att['type']=='decimal'){
		  $culture = sfContext::getInstance()->getUser()->getCulture(); 
		  $formatter = new sfNumberFormat($culture);
		  if($self[$fieldName]!=''){
		  	  $html .= $formatter->format($self[$fieldName], '#.00');
		  }
    	    //$html .= format_date($self->$fieldName,'d/M/y' );  		
    	}elseif($att['type']=='timestamp'){
		  $culture = sfContext::getInstance()->getUser()->getCulture(); 
		  $dateFormatter = new sfDateFormat($culture);
		  if($self[$fieldName]!=''){
		  	  $html .= $dateFormatter->format($self[$fieldName], 'dd/MM/yyyy HH:ss', null);
		  }
    	    //$html .= format_date($self->$fieldName,'d/M/y' );  		
    	}elseif($att['type']=='blob'){
    	 	$html .= ' ' . nl2br($self[$fieldName]);
    	}elseif($att['type']=='function'){
    		/*I have to get the object to execute de function*/
    		$obj =  Doctrine::getTable($this->className)->find($self['id']);
    		$html .= $obj->$fieldName();
    	}elseif($att['type']=='CheckboxList'){
       		$relatedClass= $att['relatedClass'];
			$refClass = $att['refClass'];
       		$relatedObjDef = new objectDef ($relatedClass);
       		$refObjDef = new objectDef ($refClass);
       		if($relatedObjDef->classExists){
       			$descriptor = $relatedObjDef->descriptor;
				$relation = $this->getRelationDef($fieldName);
				$foreingField = $relation->getForeign();
				$alias = $relation->getAlias();
					
				$q =  Doctrine::getTable($this->className)
	 				->createQuery('a')
	 				->select('a.id');
       			$q->innerJoin('a.' . $refClass . ' b');
       			$q->where('id = ?',$self['id']);
        			
       			$relation = $this->getRelationDef($refClass);
       			$relations = Doctrine::getTable($refClass)->getRelations();
       			foreach($relations as $item){
       				if(strtolower($relatedClass)==strtolower($item->getClass())){
       					$relation = $item;
       				}
       			}
       			$identifiers = Doctrine::getTable($refClass)->getIdentifier();
       			if(is_array($identifiers)){
       				foreach($identifiers as $ident){
       					$q->addSelect('b.' . $ident);
       				}
       			}else{
       				$q->addSelect('b.' . Doctrine::getTable($refClass)->getIdentifier()); //The left side of the join between the aliases 'b' and 'c' must have at least the primary key field(s) selected.	
       			}        			
       			$q->innerJoin('b.' . $relation->getAlias() . ' c');
        		$q->addSelect('c.' . $relatedObjDef->descriptor);
				$results = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
				foreach($results as $result){
					foreach($result[$refClass] as $item){
						$html .=  $item[$relatedClass][$descriptor] .'<br />';
					}
				}
       		}
    	}elseif($att['type']=='BOList'){
    	
        }elseif($att['type']=='BO'){
        		$fieldName2 = $fieldName.'_id';
	        	if($att['relatedClass']!=''){
	        		$alias = $att['alias'];
	        		$relatedClass = $att['relatedClass'];
					$relatedObjDef = new objectDef ($relatedClass);
					$relatedObject = Doctrine::getTable($relatedClass)->find($self[$fieldName2]);
			       	if($relatedObject and $relatedObjDef->classExists){
						$descriptor = $relatedObjDef->descriptor;
						$html .=  $relatedObject[$descriptor];
					}else{
						$html .= $self[$fieldName2] ;
					}
					unset($relatedObjDef);
				}else{
					$html .= $self[$fieldName2] ;
				}
        }else{
        	if(substr($self[$fieldName], 0, 4) == 'http' or substr($self[$fieldName], 0, 3) == 'www'){
	        	$html .= link_to( $self[$fieldName], $self[$fieldName], array('target'=>'_blank'));
	        }else{
	        	$valeur = $self[$fieldName];
		    	$action = $this->getCandidatesArray(false);
				if(in_array($valeur,array_keys($action)))
				{
					$valeur = $action[$valeur];
				}
				if($att['pattern']=='tel'){
					if(function_exists('format_phone'))
					{
						$valeur = format_phone($valeur, '00 00 00 00 00');
					}
				}elseif($att['pattern']=='email'){
					$valeur = '<a href="mailto:' . $valeur . '">' . $valeur . '</a>';
				}
	        	$html .= $valeur;
	        }	
        }
        return $html;
   	}   	
   	
   	public function renderLabel($fieldName){
   		$att = $this->attributes[$fieldName];
   		$i18N = sfContext::getInstance()->getI18N();
   		$label = $att['label']!='' ?  $i18N->__($att['label'], null, 'forms'):  $i18N->__($fieldName, null, 'forms');
   		return $label;
   	}
   	
	/* Renders a header to be used as a header to show the items table
   	 * 
   	 * 
   	 * @param array  $hide     | Attributes not to be rendered
   	 * @param string $style    | Render style table or div
   	 * @param boolean $addActions
   	 * @param integer $width
   	 * @param boolean $addOrderLink
   	 * @param string $orderFunctionParams
   	 * @param string $orderField
   	 * @param array $add
   	 * @param boolean $useShowAtt  | How to decide to show or hide an attribute. If false, 'list' else 'show'. Usefull to render items list on forms.
   	 * */
   	
   	public function renderListHeader($hide = null, $style = 'table', $addActions = true, $width = 0, $addOrderLink = false, $orderFunctionParams = '', $orderField = '', $add = array(), $useShowAtt = false){
   		if(is_null($hide))
   			$hide = array();
		$html = '';
		$i18N = sfContext::getInstance()->getI18N();
		if($style == 'table')
		{
			$html .= '<thead class="list_header" ><tr>'; 
			if($addActions) $html .= '<th>';
		}
		else
		{
			$html .= '<div class="list_header" ><span class="col_header">';
		}
		if($addActions){
			$html .= $i18N->__('Actions');
		}
   		if($style == 'table' and $addActions)
		{
			$html .= '</th>';
		}
		else
		{
			$html .= '</span>';
		}
		
		
   		if($orderField != ''){
	   		$orderColArray=explode('*',$orderField);
	   	}
	   	if($useShowAtt)
	   	{
	   		$attConfig = 'show';
	   	}else {
	   		$attConfig = 'list';
	   	}
   		foreach($this->attributes as $fieldName => $att){
	   		if(($att[$attConfig] or in_array($fieldName, $add)) and !in_array($fieldName, $hide) and $att['type'] != 'List'){
	   			if($style == 'table'){
	   				$html .= '<th>';
	   			}else{
	   				$html .= '<span class="col_header">';
	   			}
	   			$html .= $this->renderLabel($fieldName);
	   			if($orderField != ''){
	   				if($orderColArray[0]==$fieldName){
	   					if($orderColArray[1]=='desc'){
	   						$icon = 'arrow-down.gif';
	   					}else{
	   						$icon = 'arrow-up.gif';
	   					}
	   					$html .= '&nbsp;<img src="/images/icons/'.$icon.'"/>';
	   				};
	   			}
	   			
	   			if($addOrderLink and $att['type'] <> 'function' and $att['type'] <> 'List'){
	   				if($orderFunctionParams != ''){
	   					$comma = ',';
	   				}else{
	   					$comma = '';
	   				}
	   				$html .= '<br /><a href="javascript:refresh('.$orderFunctionParams.$comma.'\''.$fieldName.'*asc\');"><img src="/images/icons/16/sort_asc.png" title="'.$i18N->__('Sort A to Z').'"/></a>'; 
	   				$html .= '&nbsp;&nbsp;<a href="javascript:refresh('.$orderFunctionParams.$comma.'\''.$fieldName.'*desc\')"><img src="/images/icons/16/sort_desc.png" title="'.$i18N->__('Sort Z to A').'"/></a>';
	   			}
	   			if($style == 'table'){
	   				$html .= '</th>';	
	   			}else{
					$html .= '</span>';
				}
	   		}
   		}
   		if($style == 'table')
   		{
   			$html .= '</tr></thead>';
   		}
   		else
   		{
   			$html .= '</div>';
   		}
   		return $html;
   	}
   	
   	public function renderListFooter($hide = null, $style = 'table', $addActions =true, $width = 0, $add = array(), $useShowAtt = false){
   		if(is_null($hide))
   			$hide = array();
		$html = '';
		$i18N = sfContext::getInstance()->getI18N();
		if($style == 'table')
		{
			$html .= '<tfooter class="list_footer" ><tr>'; 
			if($addActions) $html .= '<th>';
		}
		else
		{
			$html .= '<div class="list_footer" ><span class="col_footer">';
		}
   		if($style == 'table' and $addActions)
		{
			$html .= '</th>';
		}
		else
		{
			$html .= '</span>';
		}
		
		
	   	if($useShowAtt)
	   	{
	   		$attConfig = 'show';
	   	}else {
	   		$attConfig = 'list';
	   	}
   		foreach($this->attributes as $fieldName => $att){
	   		if(($att[$attConfig] or in_array($fieldName, $add)) and !in_array($fieldName, $hide) and $att['type'] != 'List'){
	   			if($style == 'table'){
	   				$html .= '<th>';
	   			}else{
	   				$html .= '<span class="col_header">';
	   			}
	   			if(array_key_exists($fieldName, $this->attributesWithTotal)){
	   				$html .= $this->attributesWithTotal[$fieldName]['value'];
	   			}
	   			if($style == 'table'){
	   				$html .= '</th>';	
	   			}else{
					$html .= '</span>';
				}
	   		}
   		}
   		if($style == 'table')
   		{
   			$html .= '</tr></thead>';
   		}
   		else
   		{
   			$html .= '</div>';
   		}
   		return $html;
   	}
   	
   	
   	
   	public function renderListAttributes($item, $hide,$style = 'table'){
   		if(is_null($hide))
   			$hide = array();
		$html = '';
		foreach($this->attributes as $fieldName => $att){
	   		if($att['list'] and !in_array($fieldName, $hide) and $att['type'] != 'List'){
				if($style == 'table'){
		   			$html .= '<td>';
		   		}else{
		   			$html .= '<span class="list_cell">';
		   		}
		   		$html .= $this->renderAttributeValue($item, $fieldName);
		   		if($style == 'table'){
		   			$html .= '</td>';
		   		}else{
		   			$html .= '</span>';
		   		}
	   		}
			
		}
		return $html;
   	}
   	
   	public function renderListTable($items, $module, $hide = null, $addFieldSet = true, $addCreate = true, $addActions = true, $addExports = false, $tableClass = 'list_table', $addOrderLink = false, $orderFunctionParams = '', $ajaxActions = false, $ownerFieldName ='', $exportParams = '', $owner_id = null){
   		
   		$iconsSize = sfConfig::get('app_defaultViewer_iconssize', '16');
   		$i18N = sfContext::getInstance()->getI18N();
   		
   		$owner_param = '';
   		if(!is_null($owner_id)) $owner_param = '&owner_id=' . $owner_id;
   		
   		if(is_null($hide))
   			$hide = array();
   		$html = '';	
   		$html .= '<div class="listTable">';
   		if($addFieldSet){
			$html .= '<fieldset id="'.$ownerFieldName.'"><legend>'. $i18N->__('List of '). $i18N->__($this->labelPlural,null,'forms') .'</legend>';
   		}
   		if($addCreate){
   			if($ajaxActions){
   				$html.= '<a href="javascript:showForm(\''.$this->className.'\' , \''.$ownerFieldName.'\',\'new\');">';
				$html.= '<img src="/images/icons/'.$iconsSize.'/add.png" title="'.$i18N->__('Create New').'"'. $this->label.'/>';
				$html.= '</a>';
   			}else{
				$html .= link_to('<img src="/images/icons/'.$iconsSize.'/add.png" title="'.$i18N->__('Create New').'"'. $this->label.'/>', $module.'/new?className='.$this->className . $owner_param);
   			}
   		}
   		if($addExports){
   			if(!$ajaxActions){
	   			$exportFormat = sfConfig::get('app_defaultViewer_exportFormat', 'csv');
	   			if($exportParams!='') $exportParams = '&' . $exportParams;
	   			$html .= link_to('<img src="/images/icons/'.$iconsSize.'/export.png"  style="margin-left:5px;" title="'.$i18N->__('Export ').'"'. $this->label.'/>', $module.'/export?className='.$this->className.'&format='. $exportFormat . $exportParams);
   			}
   		}
		$html .= '<div id="list_'. $this->className.'"></div>';
		$html .= '<table class="'.$tableClass.'">';
		$html .= $this->renderListHeader($hide,'table',$addActions, 0, $addOrderLink, $orderFunctionParams);
		$html .= '<tbody class="list_elem">';
		if(is_array($items)){
			$keys=array_keys($items);
		}
		$i=0;
		$key=0;
		foreach($items as $item){
			$html .= '<tr>';
			if($addActions){
				if($ajaxActions){
					if(isset($keys)) $key=$keys[$i];
					$html .= '<td>';
	   				$html.= '<a href="javascript:showForm(\''.$this->className.'\',\''.$ownerFieldName.'\','.$key.');">';
					$html.= '<img title = "'.$i18N->__('Edit').'" src="/images/icons/'.$iconsSize.'/edit.png"/>';
					$html.= '</a>';
					$html.= '<a href="javascript:deleteItem(\''.$ownerFieldName.'Form\',\''.$this->className.'\',\''.$ownerFieldName.'\','.$key.');">';
					$html.= '<img title = "'.$i18N->__('Delete').'" src="/images/icons/'.$iconsSize.'/delete.png"/>';
					$html.= '</a>';
					$html .= '</td>';
	   			}else{
					$html .= '<td>'.link_to('<img title = "'.$i18N->__('Show').'" src="/images/icons/'.$iconsSize.'/show.png"/>', $module. '/show?id='.$item['id'].'&className='.$this->className . $owner_param);
					if(!$this->isReadOnly) 
						$html .= link_to('<img title = "'.$i18N->__('Edit').'" src="/images/icons/'.$iconsSize.'/edit.png"/>', $module.'/edit?id='.$item['id'].'&className='.$this->className . $owner_param);
					if($this->canBeDeleted) 
						$html .= link_to('<img title = "'.$i18N->__('Delete').'" src="/images/icons/'.$iconsSize.'/delete.png"/>', $module.'/delete?id='.$item['id'].'&className='.$this->className . $owner_param, array('method' => 'delete', 'confirm' => $i18N->__('Are you sure')));
					$html .= '</td>';
	   			}
			}
			$html .= $this->renderListAttributes($item, $hide);
			if(count($this->attributesWithTotal)>0){
				foreach ($this->attributesWithTotal as $fieldname => $config){
					$this->attributesWithTotal[$fieldname]['value'] = $this->attributesWithTotal[$fieldname]['value'] + $item[$fieldname]; 
				}
			}
			$html .= '</tr>';
			$i++;
		}	
		if(count($this->attributesWithTotal)>0){
			$html .= $this->renderListFooter($hide,'table',$addActions, 0);
		}
		
		$html .= '<input type="hidden" id="q_list_'. $this->className.'" value="' . $i . '">';
		$html .=  '</tbody></table>';
		if($addFieldSet){
			$html .=  '</fieldset>';
		}
		$html .=  '</div>';
		
		return $html;
   	}
   	   	
   	public function renderImage($self, $fieldName, $attDef, $options = array(), $origin = '', $printLabel = false)
   	{
   			$html = '';
   			if($origin==''){
   				if(empty($this->filesPathName)){
   					$origin = 'upload';
   				}else{
   					$origin = $this->filesPathName;
   				}
   			}
   		    $namefile = $self[$fieldName];
   			if($attDef['label']!='' and $printLabel){
				 $html .= '<label>'.$attDef['label'].' : </label>';
			} 
			if($namefile!=''){
				$html .= image_tag($origin.'/'.$namefile, $options);
			}
			return $html;   		
   		
   	}
   	
   	public function renderFile($self, $fieldName, $attDef, $origin = '', $printLabel = false){
    		$context = sfContext::getInstance();
			$context->getConfiguration()->loadHelpers(array('Tag', 'Url'));
   			
   			$html = '';
   			if($origin==''){
   				if(empty($this->filesPathName)){
   					$origin = 'upload';
   				}else{
   					$origin = $this->filesPathName;
   				}
   			}
   		    $namefile = $self[$fieldName]; 
			if($namefile!=''){
				$html .= '<input type="hidden" value="true" id="hasfile'.$fieldName.'"/>';
				if($attDef['label']!='' and $printLabel){
				 	$html .= '<label>'.$attDef['label'].' : </label>';
				}
				$description = '';
				if($attDef['fileName']!='')
					$description = $attDef['fileName'];
				if($attDef['fileNameAttribute']!=''){
					$fileNameAttribute = $attDef['fileNameAttribute']; 
					$description = $self[$fileNameAttribute]; 
				}
				$fileNamePattern = $attDef['fisicalFileNamePattern'];
				if($fileNamePattern == 'originalFileName'){
					$pathInfo = pathinfo($self[$fieldName]);
                   	$description = $pathInfo['filename'];
				}
				if($description==''){
					$descriptionLien = sfContext::getInstance()->getI18N()->__('Download File');
					$description = sfContext::getInstance()->getI18N()->__('File');
				}else{
					$descriptionLien = $description;
				}
				$descriptionLien = str_replace("'", "", $descriptionLien);
				if(function_exists('link_to')){
					$html .= link_to($descriptionLien, 'fileMng/downloadFile?name='. $namefile .'&origin='.$origin.'&description=' . $description);
				}
			}else{
				$html .= '<input type="hidden" value="false" id="hasfile'.$fieldName.'"/>';
			}
			return $html;
   		
   	}
   	
    public function getListHeaderJSON($hide = null, $addActions = true, $width = 0)
    {
   		if(is_null($hide))
   			$hide = array();
		$html = '';
		$i18N = sfContext::getInstance()->getI18N();
		
		if($addActions)
		{
			$html .= $i18N->__('Actions');
		}
		$headers = array();
   		foreach($this->attributes as $fieldName => $att)
   		{
	   		if($att['list'] and !in_array($fieldName, $hide) and $att['type'] != 'List')
	   		{
	   			if($this->charset=='utf8')
	   			{
	   				$label = $att['label']!='' ?  $i18N->__($att['label'], null, 'forms'):  $fieldName;
	   				$headers[]=array("text"=>$label,'key'=>$fieldName);
	   			}
	   			else
	   			{
	   				$label = $att['label']!='' ?  utf8_decode($i18N->__($att['label'], null, 'forms')):  $fieldName;
	   				$headers[]=array("text"=>$label,'key'=>$fieldName);
	   			}
	   		}
   		}
   		return $headers;
   	}
   	
	public function getListAttributesJSON($item, $hide,$id){
   		if(is_null($hide))
   			$hide = array();
		$html = '';
		$array = array();
		foreach($this->attributes as $fieldName => $att){
	   		if($att['list'] and !in_array($fieldName, $hide) and $att['type'] != 'List'){
		   		//{"id":0,"ID":1203,"Price":"$1.29","Title":"Websters Dictionary","Author":"Jon Stewart","Publisher":"Bantam","Year":"1972"}
				$array[$fieldName]=$this->renderAttributeValue($item, $fieldName);
	   		}
			
		}
		return $array;
   	}
   	
   	public function getListDataJSON($items, $module, $hide = null, $addFieldSet = true, $addCreate = true, $addActions = true, $addExports = false, $tableClass = 'flexme2'){
   		$iconsSize = sfConfig::get('app_defaultViewer_iconssize', '16');
   		$i18N = sfContext::getInstance()->getI18N();
   		if(is_null($hide))
   			$hide = array();
/*   	if($addFieldSet){
			$html .= '<fieldset><legend>'. $i18N->__('List of '). $this->labelPlural .'</legend>';
   		}
   		if($addCreate){
			$html .= link_to('<img src="/images/icons/'.$iconsSize.'/add.png" title="'.$i18N->__('Create New').'"'. $this->label.'/>', $module.'/new?className='.$this->className);
   		}
   		if($addExports){
   			$html .= link_to('<img src="/images/icons/'.$iconsSize.'/export.png"  style="margin-left:5px;" title="'.$i18N->__('Export ').'"'. $this->label.'/>', $module.'/export?className='.$this->className);
   		}*/
   		$data = array();
   		$i=0;
		foreach($items as $item){
			/*if($addActions){
				$html .= '<td>'.link_to('<img title = "'.$i18N->__('Show').'" src="/images/icons/'.$iconsSize.'/show.png"/>', $module. '/show?id='.$item->id.'&className='.$this->className);
				if(!$this->isReadOnly) 
					$html .= link_to('<img title = "'.$i18N->__('Edit').'" src="/images/icons/'.$iconsSize.'/edit.png"/>', $module.'/edit?id='.$item->id.'&className='.$this->className);
				if($this->canBeDeleted) 
					$html .= link_to('<img title = "'.$i18N->__('Delete').'" src="/images/icons/'.$iconsSize.'/delete.png"/>', $module.'/delete?id='.$item->id.'&className='.$this->className, array('method' => 'delete', 'confirm' => $i18N->__('Are you sure')));
				$html .= '</td>';
			}*/
			$data[] = $this->getListAttributesJSON($item, $hide,$i);
			$i++;
		}	
		/*if($addFieldSet){
			$html .=  '</fieldset>';
		}*/
		
		return $data;
   	}

   	public function getCandidatesArray($addEmpty = true, $returnKeys=array()){
   		return(array());
   		if(class_exists('erdfFuncs')){
   			$funcs = new erdfFuncs;
			return $funcs->getArrayActions($addEmpty, $returnKeys);
   		}else{
			return(array());
		}
		//return(array());
   	}   	
   	
	public function getBaseQuery($hide = array(), $add=array(), $orderBy=array()){
		$q = Doctrine::getTable($this->className)
		 		->createQuery('a')
		 		;
		if(count($add)==0){
			$q->addSelect('*');
		} 		
		
		$joinCount = 0;
		foreach($this->attributes as $fieldName => $att){
			if(($att['list'] and !in_array($fieldName, $hide) and $att['type'] != 'List')or in_array($fieldName, $add)) {
				if($att['type']=='BO'){
					$joinCount++;
					$relatedClass = $att['relatedClass'];
					$relatedObjDef = new objectDef ($relatedClass);
					$fieldName2 = $fieldName.'_id';
					$relations = Doctrine::getTable($this->className)->getRelations();
		        	foreach ($relations as $name => $relation) {
						if($relation->getType() == 0){
		    				if(strtolower($fieldName2)==strtolower($relation->getLocal())){
		    					$relatedClass = $relation->getClass();
		    					$alias = $name;
		    				}
						}
					}					
			        if($relatedObjDef->classExists){
						$q->leftJoin('a.'.$alias ." j$joinCount");
						$q->addSelect('j'.$joinCount.'.'.$relatedObjDef->descriptor);
					}else{
						$q->addSelect($fieldName2);
					}
				}elseif($att['type']=='BOList'){
					$joinCount++;
					$relatedClass = $att['relatedClass'];
					$relatedObjDef = new objectDef ($relatedClass);
					$fieldName2 = $fieldName.'_id';
					$relations = Doctrine::getTable($this->className)->getRelations();
		        	foreach ($relations as $name => $relation) {
						if($relation->getType() == 1){
		    				if(strtolower($fieldName2)==strtolower($relation->getLocal())){
		    					$relatedClass = $relation->getClass();
		    					$alias = $name;
		    				}
						}
					}					
			        if($relatedObjDef->classExists){
						
			        	$q->leftJoin('a.'.$alias ." j$joinCount");
						foreach($relatedObjDef->attributes as $relFieldName => $relAtt){
							if($relAtt['list'] and $relAtt['type'] != 'List'){
								$relFieldName2 = $relFieldName;
								if($relAtt['type']=='BO'){
									$relFieldName2 .= '_id';
									$joinCount++;
									$relations = Doctrine::getTable($relatedObjDef->className)->getRelations();
						        	$relatedClass = $relAtt['relatedClass'];
									$relatedObjDef = new objectDef ($relatedClass);
									foreach ($relations as $name => $relation) {
										if($relation->getType() == 0){
						    				if(strtolower($fieldName2)==strtolower($relation->getLocal())){
						    					$relatedClass = $relation->getClass();
						    					$alias = $name;
						    				}
										}
									}					
							        if($relatedObjDef->classExists){
							        	$oldjoin = $joinCount - 1;
										$q->leftJoin('j'. $oldjoin . ".$relFieldName j$joinCount");
										$q->addSelect('j'.$oldjoin.'.id');
										$q->addSelect('j'.$joinCount.'.'.$relatedObjDef->descriptor);
									}else{
										$q->addSelect($fieldName2);
									}
								}
								else
								{
									$q->addSelect('j'.$joinCount.'.'.$relFieldName2);	
								}
								
							}
						}
					}else{
						$q->addSelect($fieldName2);
					}
				}elseif($att['type']=='function'){
					
				}else{
					$q->addSelect($fieldName);
				}
			}
		}
		if(count($orderBy)==0)
		{
	  		$orderByCol =  $this->orderFields;
	  		if($orderByCol=='') {
	  			$orderByCol = $this->descriptor.'*asc';	
	  		}

  			$orderSens = 'asc';
			$arrayTmp = explode(';',$orderByCol);
    		foreach($arrayTmp as $orderString){
    			$orderColArray=explode('*',$orderString);
    			if(count($orderColArray)>0){
    				if(isset($orderColArray[1]))
    					$orderSens = $orderColArray[1];
    			}
    			$orderBy[] = $orderColArray;
    		}
    		$orderBy[] = array('id',$orderSens);
		}
		foreach($orderBy as $orderField){
			$fieldName = trim($orderField[0]);
			$orderType = isset($orderField[1]) ? $orderField[1] : 'asc';
			$att = $this->attributes[$fieldName];
			if($att){
				if($att['type']=='BO'){
					$relationQueryAlias = searchBar::getQueryAlias($q,$att['alias']);
					$relatedClass = $att['relatedClass'];
					$relatedObjDef = new objectDef ($relatedClass);
					if($relationQueryAlias!='')
					{
						$q->addOrderBy($relationQueryAlias.'.' . $relatedObjDef->descriptor . " $orderType");
					}
					else
					{
						Util::sendDebug('Error : Alias query Not Found!');
					} 
				}else{
		 	 		$q->addOrderBy("a.$fieldName $orderType");
				}
			}
			
		}	
    	return $q;
	}
	
	/*
	 * Gets un array with the relation name and the objectDef corresponding to to the fieldname
	 * If the application doesn't find the related Object def. It might not be defined the foreing field on the owner_id field of the item objectdef.
	 * 
	 * 
	 * @param string $fieldName
	 * @param int 	 $type 						0 Dotrine relation type for one to one relations, 1 to one to many or many to many relations.
	 * @param boolean $returnArrayWithName   	whether return an array with the name and the objectDef or only the objectDef.
	 * 
	 * @return [array | objectDef] 
	 * 
	 * If array is returned : 	array[0] string relation name
	 * 							array[1] object objectDef instance	
	 * 
	 * */
	function getRelatedObjectdef($fieldName, $type = 0, $returnArrayWithName = true){
		if(array_key_exists($fieldName,$this->attributes)){
			$doctrineFieldName = $fieldName . '_id';
		}else{
			$doctrineFieldName = $fieldName;
		}
		$relations = Doctrine::getTable($this->className)->getRelations();
		$relatedObjDef = null;
		$relationName = '';
        foreach ($relations as $name => $relation) {
        	/*echo "name : $name <br />";
        	echo 'type : ' . $relation->getType() . ' <br />' ;
        	echo 'local : ' . strtolower($relation->getLocal()) . ' <br />' ;*/
        	if($relation->getType() == $type){
				if(strtolower($doctrineFieldName)==strtolower($relation->getLocal()) or $doctrineFieldName==$name){
    				$relatedClass = $relation->getClass();
    				$relatedObjDef = new objectDef ($relatedClass);
    				$relationName = $name;
    			}
			}
		}
		if($returnArrayWithName){
			return array($relationName, $relatedObjDef);
		}else{
			return $relatedObjDef;
		}
		
	} 

	/*
	 * Gets the relationship defintinion qui corresponding to the fieldname
	 * 
	 * @param string $fieldName
	 * 
	 * @return Doctrine_Relation 
	 * 
	 * */
	function getRelationDef($fieldName){
		$relations = Doctrine::getTable($this->className)->getRelations();
		$relatedObjDef = null;
		$relationName = '';
        foreach ($relations as $name => $relation) {
    		if(strtolower($fieldName)==strtolower($relation->getLocal()) or $fieldName==$name){
    			return $relation;
    		}
		}
	}  
	
	function setReadOnly($state = true){
		$this->isReadOnly = $state;	
	}
}